package com.linzm.leetcode.primary.链表;

import org.junit.Test;

/**
 * @Author zimingl
 * @Date 2022/10/6 19:48
 * @Description: TODO
 */
public class 链表203移除链表元素 {

    /**
     * 添加虚节点方式
     * 时间复杂度 O(n)
     * 空间复杂度 O(1)
     * @param head
     * @param val
     * @return
     */
    public ListNode removeElements(ListNode head, int val) {
        if (head == null) {
            return head;
        }
        // 因为删除可能涉及到头节点，所以设置dummy节点，统一操作
        ListNode dummy = new ListNode(-1, head);
        ListNode pre = dummy;
        ListNode cur = head;
        while (cur != null) {
            if (cur.val == val) {
                pre.next = cur.next;
            } else {
                pre = cur;
            }
            cur = cur.next;
        }
        return dummy.next;
    }

    @Test
    public void test(){
        ListNode listNode7 = new ListNode(6, null);
        ListNode listNode6 = new ListNode(5, listNode7);
        ListNode listNode5 = new ListNode(4, listNode6);
        ListNode listNode4 = new ListNode(3, listNode5);
        ListNode listNode3 = new ListNode(6, listNode4);
        ListNode listNode2 = new ListNode(2, listNode3);
        ListNode head = new ListNode(1, listNode2);

        ListNode listNode = removeElements(head, 6);

    }

    /**
     * 不添加虚拟节点方式
     * 时间复杂度 O(n)
     * 空间复杂度 O(1)
     * @param head
     * @param val
     * @return
     */
    public ListNode removeElements2(ListNode head, int val) {
        while (head != null && head.val == val) {
            head = head.next;
        }
        // 已经为null，提前退出
        if (head == null) {
            return head;
        }
        // 已确定当前head.val != val
        ListNode pre = head;
        ListNode cur = head.next;
        while (cur != null) {
            if (cur.val == val) {
                pre.next = cur.next;
            } else {
                pre = cur;
            }
            cur = cur.next;
        }
        return head;
    }

    @Test
    public void test2(){
        ListNode listNode7 = new ListNode(6, null);
        ListNode listNode6 = new ListNode(5, listNode7);
        ListNode listNode5 = new ListNode(4, listNode6);
        ListNode listNode4 = new ListNode(3, listNode5);
        ListNode listNode3 = new ListNode(6, listNode4);
        ListNode listNode2 = new ListNode(2, listNode3);
        ListNode head = new ListNode(1, listNode2);

        ListNode listNode = removeElements2(head, 6);

    }

    /**
     * 不添加虚拟节点and pre Node方式
     * 时间复杂度 O(n)
     * 空间复杂度 O(1)
     * @param head
     * @param val
     * @return
     */
    public ListNode removeElements3(ListNode head, int val) {
        while(head!=null && head.val==val){
            head = head.next;
        }
        ListNode curr = head;
        while(curr!=null){
            while(curr.next!=null && curr.next.val == val){
                curr.next = curr.next.next;
            }
            curr = curr.next;
        }
        return head;
    }

    @Test
    public void test3(){
        ListNode listNode7 = new ListNode(6, null);
        ListNode listNode6 = new ListNode(5, listNode7);
        ListNode listNode5 = new ListNode(4, listNode6);
        ListNode listNode4 = new ListNode(3, listNode5);
        ListNode listNode3 = new ListNode(6, listNode4);
        ListNode listNode2 = new ListNode(2, listNode3);
        ListNode head = new ListNode(1, listNode2);

        ListNode listNode = removeElements3(head, 6);

    }
}
